/******************************************************************************
 *  _____     _____
 *  \  __\    \  __\
 *   \ \_\\    \ \_\\
 *    \  __\SS  \  __\roject
 *     \_\       \_\
 *
 * Mateusz Maciąg, Rafał Urbański
 * Komputerowe Systemy Sterowania
 *****************************************************************************/

#include "IConfigurable.h"

#include <sstream>
#include <iostream>

namespace RafMat
{
namespace SimInterface
{

using namespace std;

int IConfigurable::m_livingObjCount = 0;

IConfigurable::IConfigurable(std::string name)
    : m_name(name)
{
    m_livingObjCount++;
    cout << "IConfigurable created: " << getName() << endl;
}

IConfigurable::~IConfigurable()
{
    m_livingObjCount--;
    cout << "IConfigurable destroyed: " << getName() << endl;
}

//
// Klasa wyjątku do obsługi błędów klasy IConfigurable.
//

iconf_error::iconf_error(const std::string& __arg)
    : logic_error(__arg) {}

iconf_error::iconf_error(const IConfigurable& conf, const string& expr,
                         const string& msg)
    : logic_error(
        string("An error occured when writing/reading configuration of '")
        + conf.getName() + "'. "
        "There are some problems with expression '" + expr + "'. " + msg
    )
{
}

iconf_error iconf_error::tooHighDelay(const IConfigurable& c, const string& param,
                                      unsigned int shouldBe, unsigned int thereIs)
{
    string msg;
    ostringstream stream(msg);

    stream  << "Delay value is higher than defined when ARX was created. "
            << "Maximum value for this model is '" << shouldBe
            << "' but user wishes '" << thereIs << "'.";

    return iconf_error(c, param, stream.str());
}

iconf_error iconf_error::tooHighD(const IConfigurable& c, const string& param,
                                      unsigned int shouldBe, unsigned int thereIs)
{
    string msg;
    ostringstream stream(msg);

    stream  << "D value is higher than defined when ARMAX was created. "
            << "Maximum value for this model is '" << shouldBe
            << "' but user wishes '" << thereIs << "'.";

    return iconf_error(c, param, stream.str());
}

iconf_error iconf_error::tooHighDegree(const IConfigurable& c, const string& param,
                                      unsigned int shouldBe, unsigned int thereIs)
{
    string msg;
    ostringstream stream(msg);

    stream  << "Given polynomial has higher degree than it was supposed when "
               "ARX was created. Maximum value for this model is '" << shouldBe
            << "' but user wishes '" << thereIs << "'.";

    return iconf_error(c, param, stream.str());
}

iconf_error iconf_error::badSwitchTime(const IConfigurable& c, const string& param,
                                       unsigned int thereIs)
{
    string msg;
    ostringstream stream(msg);

    stream  << "Switch time '" << thereIs << "' is incorrect. "
               "Values below -1 are reserved. Note that 0 or -1 "
               "is used to define the stationary model or start condition "
               "of the non-stationary model.";

    return iconf_error(c, param, stream.str());
}

iconf_error iconf_error::unrecognizedParam(const IConfigurable& c, const string& param)
{
    return iconf_error(c, param, "This object does not support such parameter.");
}

iconf_error iconf_error::syntaxError(const IConfigurable& c, const string& param)
{
    return iconf_error(c, param, "Check the syntax.");
}

}   // SimInterface namespace
}   // RafMat namespace
